﻿using System;
using Porownywarka.Interfejsy;

namespace Porownywarka.Sortowanie
{
    public class QuickSort<T> :   ISortMethod<T>
        where T : IComparable<T>
    {
        public T[] SortedData { get; private set; }

        private void Swap(T[] Array, int Left, int Right)
        {
            T temp = Array[Right];
            Array[Right] = Array[Left];
            Array[Left] = temp;
        }

        public T[] Sort(T[] tablica, object l)
        {
            T[] tab2;

            lock (l)
            {
                tab2 = (T[])tablica.Clone();
            }

            SortedData = tab2;

            return Sort(ref tab2, 0, tab2.Length - 1);
        }

        public T[] Sort(ref T[] Array, int Left, int Right)
        {
            int LHold = Left;
            int RHold = Right;
            int Pivot = Left;
            Left++;


            //< 0 to this mniejsze
            while (Right >= Left)
            {
                if (Array[Left].CompareTo(Array[Pivot]) >= 0 
                        && Array[Right].CompareTo(Array[Pivot]) < 0 )
                    Swap(Array, Left, Right);
                else if (Array[Left].CompareTo(Array[Pivot]) >= 0)
                    Right--;
                else if (Array[Right].CompareTo(Array[Pivot]) < 0)
                    Left++;
                else
                {
                    Right--;
                    Left++;
                }
            }

            Swap(Array, Pivot, Right);
            Pivot = Right;
            if (Pivot > LHold)
                Sort(ref Array, LHold, Pivot);
            if (RHold > Pivot + 1)
                Sort(ref Array, Pivot + 1, RHold);

            return Array;
        }

        /*
        private T[] Sort(T[] tab, int lewy, int prawy)
        {
            int pivotIndex = (lewy + prawy)/2;
            T pivot = tab[pivotIndex];
            tab[pivotIndex] = tab[prawy];
            
            int j = lewy;
            pivotIndex = lewy;

            while (pivotIndex < prawy)
            {
                if( tab[pivotIndex].CompareTo(pivot) < 0)
                {
                    T temp = tab[pivotIndex];
                    tab[pivotIndex] = tab[j];
                    tab[j] = temp;

                    j++;
                } 

                pivotIndex++;                
            }

            tab[prawy] = tab[j];
            tab[j] = pivot;

            if(lewy < j - 1)
                Sort(tab, lewy, j - 1);
            else if (j + 1 < prawy)
                Sort(tab, j + 1, prawy);

            return tab;
        }*/
    }
}
